unit GL_GSPluginFiles;

interface

uses Classes, Graphics, GL_GSPlugin, ApplicationFileIO, GLVectorFileObjects,
  GLGraphics, GLCrossPlatform, SysUtils;

type
  TGLPluginVectorFile = class(TVectorFile)
  public
    { Public Declarations }
    class function Capabilities : TDataFileCapabilities; override;

    procedure LoadFromStream(aStream : TStream); override;
    procedure SaveToStream(aStream : TStream); override;
  end;

  TGLPluginTexture = class(TGLBaseImage)
  private
  public
    //constructor Create; override;
    class function Capabilities: TDataFileCapabilities; override;

    //procedure LoadFromFile(const filename: string); override;
    //procedure SaveToFile(const filename: string); override;
    procedure LoadFromStream(stream: TStream); override;
    procedure SaveToStream(stream: TStream); override;

    function CreateBitmap(mipLevel: integer): TBitmap;

    {
    procedure AssignFromTexture(textureContext: TGLContext;
      const textureHandle: TGLuint;
      textureTarget: TGLTextureTarget;
      const CurrentFormat: Boolean;
      const intFormat: TGLInternalFormat); override;

    property Data: PGLPixel32Array read FData;
    property Width: Integer read fWidth;
    property Height: Integer read fHeight;
    property Depth: Integer read fDepth;
    property MipLevels: Integer read fMipLevels;
    property ColorFormat: GLenum read fColorFormat;
    property InternalFormat: TGLInternalFormat read fInternalFormat;
    property DataType: GLenum read fDataType;
    property ElementSize: Integer read fElementSize;
    property CubeMap: Boolean read fCubeMap;
    property TextureArray: Boolean read fTextureArray;
    property DivScale: LongWord read FDivScale write FDivScale;
    property Dither: Boolean read FDither write FDither;
    }
  end;

implementation

uses GL_GSPluginIntf, OpenGL1x, GLTextureFormat;

type
  // Model
  TNodeData = record
    id: integer;
    name: string;
    parent: integer;
  end;
  PNodeData = ^TNodeData;

{ TGLPluginVectorFile }

class function TGLPluginVectorFile.Capabilities: TDataFileCapabilities;
begin
  Result := [dfcRead, dfcWrite];
end;

procedure TGLPluginVectorFile.LoadFromStream(aStream: TStream);
begin
  {
    procGetFileInfo
      - MeshCount
      - node count

    procGetBone(ptr, inode, PNodeData) - get node
    procGetFrames(ptr, out fcount,
    procGetFrameInfo(ptr, iframe, out pCnt,rCnt: word);
    procGetFrameData(ptr, iframe, pos: array(PVector3f); rot: array(PVector3f))

    procGetMeshData(ptr, imesh, mdf_flag, data: PVector3f): integer
      if data=nil return count
      mdf_flag: MDF_VERTICES,MDF_NORMALS,MDF_TEXCOOR,MDF_LMCOOR
    procGetFaceGroup(ptr, imesh, ifaceg, mdf_flag, data: PVector3f): integer
      if data=nil return count

  }
end;

procedure TGLPluginVectorFile.SaveToStream(aStream: TStream);
begin

end;

{ TGLPluginTexture }

class function TGLPluginTexture.Capabilities: TDataFileCapabilities;
begin
  Result := [dfcRead, dfcWrite];
end;

function TGLPluginTexture.CreateBitmap(mipLevel: integer): TBitmap;
var data: PByte;
    dSize,dPos: cardinal;
    x,y,k: integer;
    buf: PByteArray;
begin
  result := TBitmap.Create;
  result.Width := fWidth shr mipLevel;
  result.Height := fHeight shr mipLevel;
  result.PixelFormat := pf32bit;

  dsize := LevelSize(mipLevel);
  GetMem(data, dSize);
  try
    Move(GetLevelData(mipLevel)[0], data^, dsize);
    dPos := 0;
    k := result.Width*4;
    assert(k*result.height = dSize, Format('got %d expecting %d', [k*result.height, dSize]));
      for y := 0 to pred(result.Height) do begin
        buf := result.ScanLine[y];
        for x := 0 to result.Width-1 do begin
          buf^[x*4+0] := TByteRaster(data)[(y*k)+x*4+0];
          buf^[x*4+1] := TByteRaster(data)[(y*k)+x*4+1];
          buf^[x*4+2] := TByteRaster(data)[(y*k)+x*4+2];
          buf^[x*4+3] := TByteRaster(data)[(y*k)+x*4+3];
        end;
      end;
  finally
    freeMem(data);
  end;
end;

procedure TGLPluginTexture.LoadFromStream(stream: TStream);
var gsInfo: TGSImageInfo;
    plugin: TGSPlugin;
    ldata,data: PByte;
    xDataSize: cardinal;
    lev: integer;
begin
  // first find corresponding plugin
  plugin := PluginFactory.PluginByExt[xptTexture, xioRead, extractFileExt(Self.ResourceName)];
  if not assigned(plugin) then
    raise Exception.CreateFmt('Texture format "%s" is not supported by plugins!', [extractFileExt(self.ResourceName)]);

  with TGSTexturePlugin(plugin) do begin
    if not load(self.ResourceName) then
      raise Exception.CreateFmt('Failed to load texture "%s"!', [self.ResourceName]);

    info(@gsInfo);

    fWidth := gsInfo.wWidth;
    fHeight := gsInfo.wHeight;
    fDepth := gsInfo.wDepth;
    // check alpha flag
    //fTransparent := gsInfo.
    fMipLevels := gsInfo.bMipLevels;
    //check cube-map faces
    fCubeMap := gsInfo.bCubeMap;

    case gsInfo.kFormat of
      gsifRGBA: fInternalFormat := tfRGBA8;
      gsifRGB: fInternalFormat := tfRGB8;
      gsifAlpha8: fInternalFormat := tfAlpha8;
    end;
    fDataType := GL_UNSIGNED_BYTE;
    fLevels.Clear;
    fTextureArray := false;
    ReallocMem(fData, DataSize);
    lData := PByte(fData);

    // read data
    //Move(Pointer(Longint(FMemory) + FPosition)^, Buffer, Result);
    for lev := 0 to pred(FMipLevels) do begin
      xDataSize := getBits(lev, nil);
      if xDataSize > 0 then begin
        fLevels.Add(pointer(integer(lData) - integer(fData)));
        GetMem(data, xDataSize);
        if getBits(lev, data) > 0 then ;
          move(data^, lData^, xDataSize);
        FreeMem(data);
      end;
      inc(lData, xDataSize);
    end;
  end;
end;

procedure TGLPluginTexture.SaveToStream(stream: TStream);
var plugin: TGSPlugin;
    fmt: TGSImageFormat;
    ifmt: integer;
begin
  // first find corresponding plugin
  plugin := PluginFactory.PluginByExt[xptTexture, xioWrite, extractFileExt(Self.ResourceName)];
  if not assigned(plugin) then
    raise Exception.CreateFmt('Texture format "%s" is not supported by plugins!', [extractFileExt(self.ResourceName)]);

  with TGSTexturePlugin(plugin) do begin
    ifmt := InternalFormatToOpenGLFormat(fInternalFormat);
    if not make(fWidth, fHeight, fDepth, fmt, fMipLevels) then
      raise Exception.CreateFmt('Failed to load texture "%s"!', [self.ResourceName]);

  end;
end;

end.
